home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Plug-In DLL Example and Template
- * for use with C/C++
- *
- * Compile DLL with any name.
- * Place it in the program FindGraph subfolder "Appr".
- * Next functions must be exported:
- * MaxOfFactors
- * Prepare
- * CalcInPoint
- * FunctionTitle
- * FunctionName
- * FunctionString
- * ParamInfo
- *
- * To test DLL, restart FundGraph,
- * start The Wizard of approximation,
- * on step 2 select 'User defined function'.
- * If all right, on step 3 your function will appear in list.
- *
- ******************************************************************************/
-
-
- #include <windows.h>
- #include <tchar.h>
- #include <math.h>
- #include "exppow.h"
-
-
- #include <stdio.h>
-
-
- //
- #pragma comment(linker,"/MERGE:.rdata=.text")
- #pragma comment(linker,"/FILEALIGN:512 /SECTION:.text,EWRX /IGNORE:4078")
-
- //////////////////////////////////////////////////////////////////////////////////
-
-
- HINSTANCE g_hInstance=NULL;
- BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
- {
- switch (ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH:
- g_hInstance = (HINSTANCE )hModule;
- break;
- case DLL_PROCESS_DETACH:
- break;
- }
- return TRUE;
- }
-
-
-
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- #define N_FACTORS 10
- #define aa(i,j) pfs[i*nn+j]
-
- // 2 linear equations
- // Input
- // pfs = matrix [2,3]
- // Output
- // pfu - vector [2]
- //
- void CalcEquGauss2(double *pfs, double *pfu)
- {
- int n = 1,
- nn = n+2;
-
-
- double d = aa(0,0) * aa(1,1) - aa(0,1)*aa(1,0);
- if (d == 0.)
- {
- pfu[1] = 0.;
- pfu[0] = (aa(0,0) != 0.) ? aa(0,2) / aa(0,0) : 0.;
- }
- else
- {
- pfu[0] = (aa(1,1)*aa(0,2) - aa(0,1)*aa(1,2)) / d;
- pfu[1] = (aa(0,0)*aa(1,2) - aa(1,0)*aa(0,2)) / d;
- }
- }
-
-
- // Error of calculus
- //
- double CalcError(double *pfU, double *pfV, int nPoints,
- double *pfFactors, int nFactors)
- {
- if (nPoints <= 0)
- return 0.;
- double fError = 0.;
- for (int id=0; id < nPoints; id++ )
- {
- double u = pfU[id],
- v = pfV[id],
- v1= CalcInPoint(u, pfFactors, nFactors);
- fError += (v1-v)*(v1-v);
- }
- fError = sqrt(fError/nPoints);
- return fError;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- //
- // Return the number of factors (see function 'Prepare')
- // use to memory allocate for pfFactors
- //
-
- //extern "C" bool __declspec( dllexport ) __stdcall TransFromDisk(char *Base, char *Disk);
-
-
- int __declspec(dllexport) __stdcall MaxOfFactors()
- {
- return N_FACTORS;
- }
-
-
- //
- // Prepare approximation function V(U) = Function(U)
- // V(U) = V0 + exp(a*(U-U0))*Pow((U-U0), b)
- // Input:
- // Array of points (U,V)
- // fMinU, fMaxU - limits of U
- // fMinV, fMaxV - limits of V
- // pfU, pfV - array of nPoints points (U,V)
- // pfW - weight of point
- // nPoints - number of points in array
- // Parameters:
- // pfParams - array of parameters
- // U0 = pfParams[0]
- // V0 = pfParams[1]
- // nParams - number of parameters in array
- //
- // Output:
- // Array of factors is calculated.
- // This factors will be used in function CalcInPoint(U, pfFactors)
- // pfFactors - array of factors, defined by user
- // Notes: pfFactors[*pnFactors-1] = Error of calculus
- // nFactors:
- // Input - maximum possible number of factors in array
- //
- // return: number of factors if success, else error code
- //
- int __declspec(dllexport) __stdcall Prepare (double fMinU, double fMaxU, double fMinV, double fMaxV,
- double *pfU, double *pfV, double *pfW, int nPoints,
- double *pfParams , int nParams ,
- double *pfFactors, int nFactors)
- {
- int nResult = 0;
- if (nPoints < 2) // not enough points
- return -1;
-
- if (nFactors < N_FACTORS) // not enough memory for result
- return -2;
-
-
- int
- nAppr = 1,
- nn = nAppr + 2,
- ns =(nAppr+1)*(nn+1);
-
- double fU0 = fMinU,
- fV0 = fMinV;
- if (nParams > 0) fU0 = pfParams[0];
- if (nParams > 1) fV0 = pfParams[1];
-
-
- double
- *pfs,
- *pfu;
- // use: aa(i,j) == pfs[i*nn+j]
-
-
- pfu = new double[nAppr+1];// calced coeff
- pfs = new double[ns];
- memset(pfs, 0, ns*sizeof(double));
-
-
- int nSum = 0; // point with U>0, V>0
- for (int id=0; id < nPoints; id++ )
- {
- double u = pfU[id] - fU0,
- v = pfV[id] - fV0;
- if (u > 0. && v > 0.)
- {
- double lu = log(u),
- lv = log(v);
-
- aa(0,0) += u* u;
- aa(0,1) += u*lu;
- aa(0,2) += u*lv;
- aa(1,0) += lu* u;
- aa(1,1) += lu*lu;
- aa(1,2) += lu*lv;
-
- nSum++;
- }
- }
- if (nSum >= 2)
- {
- CalcEquGauss2(pfs, pfu);
- nResult = N_FACTORS;
-
- pfFactors[0] = nSum;
- pfFactors[1] = fMinU; pfFactors[2] = fMaxU; // Unused now - reserved
- pfFactors[3] = fMinV; pfFactors[4] = fMaxV; // Unused now - reserved
- pfFactors[4] = 0; // Unused now - reserved
- pfFactors[5] = fU0;
- pfFactors[6] = fV0;
- pfFactors[7] = pfu[0]; // a
- pfFactors[8] = pfu[1]; // b
-
- pfFactors[N_FACTORS-1] = CalcError(pfU, pfV, nPoints, pfFactors, nFactors);
- }
-
-
-
- delete [] pfu;
- delete [] pfs;
- return nResult;
- }
-
- // Calculate value V = Function(fU)
- // Input:
- // fU
- // pfFactors - array of factors, prepared in finction Prepare()
- // pnFactors: - number of factors in array
- //
- // return: value calculated
- //
- double __declspec(dllexport) __stdcall CalcInPoint(double fU,
- double *pfFactors, int nFactors)
- {
- double fV = 0.;
- if (nFactors < N_FACTORS)
- return 0.;
- double
- U0 = pfFactors[5],
- V0 = pfFactors[6],
- a = pfFactors[7],
- b = pfFactors[8],
- U = fU - U0;
- if (U <= 0.)
- return 0.;
- fV = V0 + exp(a*U)*pow(U, b);
-
- return fV;
- }
-
-
- // Fill information string with name of approximation method
- // It is used in FindGraph <Master of approximations page 2><list of user defined functions>
- // for example - "User's ExpPow"
- // Input:
- // pstr - buffer TCHAR
- // nMaxLength - maximum buffer length
- //
- // Output:
- // pstr - name of approximation method
- //
- // return: string length if success, else -1
- //
- int __declspec(dllexport) __stdcall FunctionTitle(LPTSTR pstr, int nMaxLength)
- {
- if (pstr==0)
- return -1;
- lstrcpyn(pstr, TEXT(" Y = Exp(a*X)*Pow(x,b) (see sample in directory \'ApprSource\')"), nMaxLength);
- return lstrlen(pstr);
- }
-
-
-
- // Fill information string with name of approximation function
- // for example - "V(U) = V0 + Exp(a*(U-U0))*Pow((U-U0), b)"
- // It is used in FindGraph <Master of approximations page 3><Function description>
- // Input:
- // pstr - buffer TCHAR
- // nMaxLength - maximum buffer length
- //
- // Output:
- // pstr - name of approximation function
- //
- // return: string length if success, else -1
- //
- int __declspec(dllexport) __stdcall FunctionName(LPTSTR pstr, int nMaxLength)
- {
- if (pstr==0)
- return -1;
- lstrcpyn(pstr, TEXT("f(U) = V0 + Exp(a*(U-U0))*Pow((U-U0), b)"), nMaxLength);
- return lstrlen(pstr);
- }
-
-
-
- // Fill information string with formula of calculated function f(U) = Formula()
- // for example - "V(U) = 1. + Exp(2*(U-3.))*Pow((U-3.), 4)"
- // It is used in FindGraph <Master of approximations pages 4 and 5>
- // Input:
- // pstr - buffer TCHAR
- // nMaxLength - maximum buffer length
- // pfFactors - array of factors, prepared in finction Prepare()
- // pnFactors: - number of factors in array
- //
- // Output:
- // pstr - string of calculated function f(U)
- //
- // return: string length if success, else -1
- //
- int __declspec(dllexport) __stdcall FunctionString(double *pfFactors, int nFactors,
- LPTSTR pstr, int nMaxLength)
- {
- if (pstr==0)
- return -1;
- if (nFactors < N_FACTORS)
- return -2;
-
- TCHAR sz[256];
- double
- U0 = pfFactors[5],
- V0 = pfFactors[6],
- a = pfFactors[7],
- b = pfFactors[8];
-
- sprintf(sz, TEXT("f(U) = %4.4g + Exp(%4.2f*(U-%4.4g))*Pow((U-%4.4g), %4.2f)"), V0, a, U0, U0, b);
- lstrcpyn(pstr, sz, nMaxLength);
- return lstrlen(pstr);
- }
-
-
-
- // Fill information string with name of parameter and it's default value
- // It is used in FindGraph <Master of approximations page 3>
- // Input:
- // nParam - number of edit box in page 3
- // 1, 2, 3, 4
- // see list of pfParams in function 'Prepare'
- // pstr - buffer TCHAR
- // nMaxLength - maximum buffer length
- //
- // Output:
- // pstr - name of parameter[nParam]
- // pfDefault - default value of parameter[nParam]
- //
- // return: string length if success, else -1
- //
- int __declspec(dllexport) __stdcall ParamInfo(int nParam, LPTSTR pstr, int nMaxLength, double *pfDefault)
- {
- if (pstr==0)
- return -1;
- switch (nParam)
- {
- case 1:
- lstrcpyn(pstr, TEXT("U0"), nMaxLength);
- if (pfDefault != NULL)
- *pfDefault = 0.;
- break;
- case 2:
- lstrcpyn(pstr, TEXT("V0"), nMaxLength);
- if (pfDefault != NULL)
- *pfDefault = 0.;
- break;
- case 3:
- case 4:
- lstrcpyn(pstr, TEXT("unused"), nMaxLength);
- if (pfDefault != NULL)
- *pfDefault = 0.;
- break;
- default: return -1;
- }
- //*pfDefault = 10+nParam;
- return lstrlen(pstr);
- }
-